//***************************************************************************
//*
//*	File:			DialogSmartReplace.cpp
//*	Description:	Smart replace dialog
//*
//***************************************************************************

//
//--------------------------------------------------------------- PRECOMPILED
//

#include "stdafx.h"

//
//--------------------------------------------------- DECLARATION DEPENDENCIES
//

#include "SmartReplace.h"

//
//--------------------------------------------------------------- DECLARATION
//

#include "DialogSmartReplace.h"

//
//--------------------------------------------------- DEFINITION DEPENDENCIES
//

#include "StringEx.h"
#include "DialogOptions.h"
#include "DialogFilters.h"
#include "FolderDialog.h"

//
//-------------------------------------------------------------- PREPROCESSOR
//

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//
//---------------------------------------------------------------- DEFINITION
//

#ifndef	MIN
#define MIN( a, b ) ( (a) < (b) ? (a) : (b) )
#endif

#ifndef	MAX
#define MAX( a, b ) ( (a) > (b) ? (a) : (b) )
#endif

static long g_GetRefCount( IUnknown* a_pIUnknown )
{
	if ( NULL == a_pIUnknown )
	{
		return 0l;
	}

			a_pIUnknown->AddRef	();
	return	a_pIUnknown->Release();
};

//
//---------------------------------------------------------------------------------------------------
//

const char* CDialogSmartReplace::ms_ppszRegExpFind[ CDialogSmartReplace::ERegExpFind_Count ][ CDialogSmartReplace::ERegExpEmulation_Count ] =
{
//	DevStd			VC2				Brief											Epsilon										Custom
	"."			,	"."			,	"?"											,	"."										,	"."				// any char
,	"[]"		,	"[]"		,	"[]"										,	"[]"									,	"[]"			// in range
,	"[^]"		,	"[^]"		,	"[~]"										,	"[^]"									,	"[^]"			// not in range
,	"^"			,	"^"			,	"%"											,	"^"										,	"^"				// begin of line
,	"$"			,	"$"			,	"$"											,	"$"										,	"$"				// end of line
,	"\\(\\)"	,	"\\(\\)"	,	"{}"										,	"()"									,	"\\(\\)"		// tagged expression
,	"\\~"		,	"\\~"		,	"~"											,	"~"										,	"\\~"			// not
,	"\\!"		,	"\\!"		,	"|"											,	"|"										,	"\\!"			// or
,	"*"			,	"*"			,	"@"											,	"*"										,	"*"				// 0 or more
,	"+"			,	"+"			,	"+"											,	"+"										,	"+"				// 1 or more
,	"\\{\\}"	,	"\\{\\}"	,	"{}"										,	"()"									,	"\\{\\}"		// group
,	"\\:b+"		,	"\\:b+"		,	"[ \x09]+"									,	"[ <tab>]+"								,	"\\:b+"			// whitespace
,	"\\:a"		,	"\\:a"		,	"[a-zA-Z0-9]"								,	"[a-zA-Z0-9]"							,	"\\:a"			// alpha numeric character
,	"\\:c"		,	"\\:c"		,	"[a-zA-Z]"									,	"[a-zA-Z]"								,	"\\:c"			// alpha character
,	"\\:d"		,	"\\:d"		,	"[0-9]"										,	"[0-9]"									,	"\\:d"			// decimal digit
,	"\\:h"		,	"\\:h"		,	"[0-9a-fA-F]+"								,	"[0-9a-fA-F]+"							,	"\\:h"			// hex number
,	"\\:n"		,	"\\:n"		,	"{[0-9]+.[0-9]@}|{[0-9]@.[0-9]+}|{[0-9]+}"	,	"([0-9]+.[0-9]*|[0-9]*.[0-9]+|[0-9]+)"	,	"\\:n"			// decimal number
,	"\\:z"		,	"\\:z"		,	"[0-9]+"									,	"[0-9]+"								,	"\\:z"			// integer
,	"\\:i"		,	"\\:i"		,	"[a-zA-Z_$][a-zA-Z0-9_$]@"					,	"[a-zA-Z_$][a-zA-Z0-9_$]*"				,	"\\:i"			// c++ identifier
,	"\\:w"		,	"\\:w"		,	"[a-zA-Z]+"									,	"[a-zA-Z]+"								,	"\\:w"			// alphabetic string (word)
,	"\\:q"		,	"\\:q"		,	"\"[~\"]@\""								,	"\"[~\"]*\""							,	"\\:q"			// quoted alphabetic string (word)
};

const char* CDialogSmartReplace::ms_ppszRegExpReplace[ CDialogSmartReplace::ERegExpReplace_Count ][ CDialogSmartReplace::ERegExpEmulation_Count ] =
{
//	DevStd			VC2				Brief											Epsilon										Custom
	"\\0"		,	"\\0"		,	"\\0"										,	"\\0"									,	"\\0"			// text
,	"\\1"		,	"\\1"		,	"\\1"										,	"\\1"									,	"\\1"			// tagged expression 1
,	"\\2"		,	"\\2"		,	"\\2"										,	"\\2"									,	"\\2"			// tagged expression 2
,	"\\3"		,	"\\3"		,	"\\3"										,	"\\3"									,	"\\3"			// tagged expression 3
,	"\\4"		,	"\\4"		,	"\\4"										,	"\\4"									,	"\\4"			// tagged expression 4
,	"\\5"		,	"\\5"		,	"\\5"										,	"\\5"									,	"\\5"			// tagged expression 5
,	"\\6"		,	"\\6"		,	"\\6"										,	"\\6"									,	"\\6"			// tagged expression 6
,	"\\7"		,	"\\7"		,	"\\7"										,	"\\7"									,	"\\7"			// tagged expression 7
,	"\\8"		,	"\\8"		,	"\\8"										,	"\\8"									,	"\\8"			// tagged expression 8
,	"\\9"		,	"\\9"		,	"\\9"										,	"\\9"									,	"\\9"			// tagged expression 9
};

//
//---------------------------------------------------------------------------------------------------
//*************************************     CON/DESTRUCTION     *************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																					  Constructor
//***************************************************************************************************
//**	@DOC		CONSTRUCTION
//**	@MFUNC		Default constructor
//**	@PARM		[in]	 Pointer to application's interface
//**	@PARM		[in|opt] Pointer to the parent window
//**	@END
//***************************************************************************************************
//inline
CDialogSmartReplace::CDialogSmartReplace( IApplication* a_pIApplication, CWnd* pParent /*=NULL*/ )
: CDialog( CDialogSmartReplace::IDD, pParent )
{
	//{{AFX_DATA_INIT(CDialogSmartReplace)
	m_bAllCases						= FALSE;
	m_bMatchCase					= FALSE;
	m_bRegularExpression			= FALSE;
	m_bWholeWord					= FALSE;
	m_strFindWhat					= _T("");
	m_strReplaceWith				= _T("");
	m_iReplaceWhereEx				= EReplaceWhereEx_AllOpen;
	m_iReplaceWhere					= EReplaceWhere_File;
	m_strDirectory					= _T("");
	m_strExtensions					= _T("");
	m_bRecurse						= FALSE;
	//}}AFX_DATA_INIT

	this->m_pIApplication			= a_pIApplication					;
	this->m_enuFindStringMode		= EFindStringMode_KeepIfNoSelection	;
	this->m_enuConfirmReplacement	= EConfirm_Never					;
	this->m_enuSaveAndClose			= ESaveAndClose_Never				;
	this->m_bAskForExtendedOnly		= FALSE								;
	this->m_bFileFinished			= FALSE								;
	this->m_lRegExpEmulation		= dsDevStudio						;
}

//
//---------------------------------------------------------------------------------------------------
//***************************************     PERSISTENCE     ***************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																					  LoadProfile 
//***************************************************************************************************
//**	@DOC		PERSISTENCE
//**	@MFUNC		Loads the dialog's settings from the registry
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::LoadProfile( void )
{
	//
	//	GET APPLICATION
	//
	CWinApp* pApp = ::AfxGetApp();

	//
	//	LOAD SECTION NAME
	//
	CString strSection; 
			strSection.LoadString( IDS_PROFILE_SECTION );

	//
	//	READ MEMBERS
	//
	this->m_bAllCases				= static_cast< BOOL					> (	pApp->GetProfileInt		( strSection, _T( "AllCases"			), FALSE								) );
	this->m_bMatchCase				= static_cast< BOOL					> (	pApp->GetProfileInt		( strSection, _T( "MatchCase"			), FALSE								) );
	this->m_bRegularExpression		= static_cast< BOOL					> (	pApp->GetProfileInt		( strSection, _T( "RegularExpression"	), FALSE								) );
	this->m_bWholeWord				= static_cast< BOOL					> (	pApp->GetProfileInt		( strSection, _T( "WholeWord"			), FALSE								) );
	this->m_bAskForExtendedOnly		= static_cast< BOOL					> (	pApp->GetProfileInt		( strSection, _T( "AskForExtendedOnly"	), FALSE								) );
	this->m_bRecurse				= static_cast< BOOL					> (	pApp->GetProfileInt		( strSection, _T( "RecurseDirectory"	), TRUE									) );
	this->m_enuFindStringMode		= static_cast< EFindStringMode		> (	pApp->GetProfileInt		( strSection, _T( "FindStringMode"		), EFindStringMode_KeepIfNoSelection	) );
	this->m_enuConfirmReplacement	= static_cast< EConfirmReplacement	> (	pApp->GetProfileInt		( strSection, _T( "ConfirmReplace"		), EConfirm_Never						) ); 
	this->m_enuSaveAndClose			= static_cast< ESaveAndClose		> (	pApp->GetProfileInt		( strSection, _T( "SaveAndClose"		), ESaveAndClose_Never					) ); 
	this->m_iReplaceWhere			=										pApp->GetProfileInt		( strSection, _T( "ReplaceWhere"		), EReplaceWhere_File					);
	this->m_iReplaceWhereEx			=										pApp->GetProfileInt		( strSection, _T( "ReplaceWhereEx"		), EReplaceWhereEx_AllOpen				);
//	this->m_strFindWhat				=										pApp->GetProfileString	( strSection, _T( "FindWhat"			) );
//	this->m_strReplaceWith			=										pApp->GetProfileString	( strSection, _T( "ReplaceWith"			) );
							
	//
	//	UPDATE CONTROLS FROM MEMBERS
	//
	this->UpdateData( EUpdateData_ToControls );

	//
	//	LOAD FILTERS
	//
	this->LoadFilters();

	//
	//	LOAD HISTORY
	//
	this->LoadHistory();

	//
	//	UPDATE CONTROLS [enable/disable controls]
	//
	this->UpdateControls();

	//
	//	SET ADVANCED MODE
	//
	this->UpdateAdvanced		(											pApp->GetProfileString	( strSection, _T( "Advanced"			) ) );
}

//***************************************************************************************************
//**																					  LoadHistory 
//***************************************************************************************************
//**	@DOC		PERSISTENCE
//**	@MFUNC		Loads the dialog's settings from the registry
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::LoadHistory( void )
{
	//
	//	GET APPLICATION
	//
	CWinApp* pApp = ::AfxGetApp();

	//
	//	LOAD SECTION NAME
	//
	CString strSection; 
			strSection.LoadString( IDS_PROFILE_SECTION );

	//
	//	SETUP VARS
	//
	CString strKey		;
	CString strValue	;
	int		iEntry		= 0;
	int		iEntries	= 0;
		
	//
	//	READ FIND STRING HISTORY
	//
	iEntries = pApp->GetProfileInt( strSection, _T( "FindWhat.Count" ), 0 );

	for ( iEntry = 0; iEntry < iEntries; iEntry++ )
	{
		strKey.Format( "FindWhat.%d", iEntry );	

		strValue = pApp->GetProfileString( strSection, strKey ); 

		this->m_ctrlComboFindWhat.AddString( /*iEntry,*/ strValue );
	}

	//
	//	READ REPLACE STRING HISTORY
	//
	iEntries = pApp->GetProfileInt( strSection, _T( "ReplaceWith.Count" ), 0 );

	for ( iEntry = 0; iEntry < iEntries; iEntry++ )
	{
		//
		//	READ ENTRY
		//
		strKey.Format( "ReplaceWith.%d", iEntry );	
		strValue = pApp->GetProfileString( strSection, strKey ); 
		this->m_ctrlComboReplaceWith.AddString( /*iEntry,*/ strValue );	
	}

	//
	//	READ DIRECTORY STRING HISTORY
	//
	iEntries = pApp->GetProfileInt( strSection, _T( "Directory.Count" ), 0 );

	for ( iEntry = 0; iEntry < iEntries; iEntry++ )
	{
		//
		//	READ ENTRY
		//
		strKey.Format( "Directory.%d", iEntry );	
		strValue = pApp->GetProfileString( strSection, strKey ); 
		this->m_ctrlComboDirectory.AddString( /*iEntry,*/ strValue );	
	}

	//
	//	SELECT FIRST ENTRIES
	//
	this->m_ctrlComboFindWhat	.SetCurSel( 0 );
	this->m_ctrlComboReplaceWith.SetCurSel( 0 );
	this->m_ctrlComboExtensions	.SetCurSel( 0 );
	this->m_ctrlComboDirectory	.SetCurSel( 0 );

	//
	//	UPDATE MEMBERS FROM CONTROLS
	//
	this->UpdateData( EUpdateData_FromControls );
}

//***************************************************************************************************
//**																					  LoadFilters 
//***************************************************************************************************
//**	@DOC		PERSISTENCE
//**	@MFUNC		Loads the dialog's settings from the registry
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::LoadFilters( void )
{
	//
	//	CLEAR ARRAYS
	//
	this->m_arrFolders	.RemoveAll();
	this->m_arrFileMasks.RemoveAll();

	//
	//	GET APPLICATION
	//
	CWinApp* pApp = ::AfxGetApp();

	//
	//	LOAD SECTION NAME
	//
	CString strSection; 
			strSection.LoadString( IDS_PROFILE_SECTION );

	//
	//	SETUP VARS
	//
	CString		strKey		;
	CString		strValue	;
	CFolder		folder		;
	CFileMask	mask		;
	int			iEntry		= 0;
	int			iEntries	= 0;
		
	//
	//	READ FOLDERS
	//
	iEntries = pApp->GetProfileInt( strSection, _T( "Folder.Count" ), 0 );

	for ( iEntry = 0; iEntry < iEntries; iEntry++ )
	{
		strKey.Format( "Folder.%d.Path"		, iEntry );	folder.m_strPath	=						pApp->GetProfileString( strSection, strKey ); 
		strKey.Format( "Folder.%d.Enabled"	, iEntry );	folder.m_bEnabled	= static_cast< BOOL > (	pApp->GetProfileInt	( strSection, strKey , FALSE ) ); 
		strKey.Format( "Folder.%d.Recurse"	, iEntry );	folder.m_bRecurse	= static_cast< BOOL > (	pApp->GetProfileInt	( strSection, strKey , FALSE ) ); 

		this->m_arrFolders.Add( folder );
	}

	//
	//	READ FILE MASKS
	//
	iEntries = pApp->GetProfileInt( strSection, _T( "FileMask.Count" ), 0 );

	for ( iEntry = 0; iEntry < iEntries; iEntry++ )
	{
		strKey.Format( "FileMask.%d.Mask"		, iEntry );	mask.m_strMask	=						pApp->GetProfileString	( strSection, strKey ); 
		strKey.Format( "FileMask.%d.Enabled"	, iEntry );	mask.m_bEnabled	= static_cast< BOOL > (	pApp->GetProfileInt		( strSection, strKey , FALSE ) ); 

		this->m_arrFileMasks.Add( mask );
	}
}

//***************************************************************************************************
//**																					 WriteProfile 
//***************************************************************************************************
//**	@DOC		PERSISTENCE
//**	@MFUNC		Saves the dialog's settings to the registry
//**	@RDESC		<t TRUE> if successful, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::WriteProfile( void ) const
{
	//
	//	GET NON-CONST POINTER TO SELF
	//
	CDialogSmartReplace* pThis = const_cast< CDialogSmartReplace* > (this);

	//
	//	UPDATE MEMBERS FROM CONTROLS
	//
	pThis->UpdateData( EUpdateData_FromControls );

	//
	//	GET ADDITIONAL STATES
	//
	CString strCaption; this->m_ctrlBtnAdvanced.GetWindowText( strCaption );

	//
	//	GET APPLICATION
	//
	CWinApp* pApp = ::AfxGetApp();

	//
	//	LOAD SECTION NAME
	//
	CString strSection; 
			strSection.LoadString( IDS_PROFILE_SECTION );

	//
	//	WRITE MEMBERS
	//
	pApp->WriteProfileInt	( strSection, _T( "AllCases"			), this->m_bAllCases				);
	pApp->WriteProfileInt	( strSection, _T( "MatchCase"			), this->m_bMatchCase				);
	pApp->WriteProfileInt	( strSection, _T( "RegularExpression"	), this->m_bRegularExpression		);
	pApp->WriteProfileInt	( strSection, _T( "WholeWord"			), this->m_bWholeWord				);
	pApp->WriteProfileInt	( strSection, _T( "AskForExtendedOnly"	), this->m_bAskForExtendedOnly 		);
	pApp->WriteProfileInt	( strSection, _T( "RecurseDirectory"	), this->m_bRecurse			 		);
	pApp->WriteProfileInt	( strSection, _T( "ReplaceWhere"		), this->m_iReplaceWhere			);
	pApp->WriteProfileInt	( strSection, _T( "ReplaceWhereEx"		), this->m_iReplaceWhereEx			);
	pApp->WriteProfileInt	( strSection, _T( "FindStringMode"		), this->m_enuFindStringMode		);
	pApp->WriteProfileInt	( strSection, _T( "ConfirmReplace"		), this->m_enuConfirmReplacement	);
	pApp->WriteProfileInt	( strSection, _T( "SaveAndClose"		), this->m_enuSaveAndClose			);
//	pApp->WriteProfileString( strSection, _T( "FindWhat"			), this->m_strFindWhat				);
//	pApp->WriteProfileString( strSection, _T( "ReplaceWith"			), this->m_strReplaceWith			);
	pApp->WriteProfileString( strSection, _T( "Advanced"			), strCaption						);

	//
	//	WRITE FILTERS
	//
	this->WriteFilters();

	//
	//	WRITE HISTORY
	//
	return this->WriteHistory();
}

//***************************************************************************************************
//**																					 WriteHistory 
//***************************************************************************************************
//**	@DOC		PERSISTENCE
//**	@MFUNC		Saves the dialog's settings to the registry
//**	@RDESC		<t TRUE> if successful, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::WriteHistory( void ) const
{
	//
	//	GET APPLICATION
	//
	CWinApp* pApp = ::AfxGetApp();

	//
	//	LOAD SECTION NAME
	//
	CString strSection; 
			strSection.LoadString( IDS_PROFILE_SECTION );

	//
	//	SETUP VARS
	//
	CString strKey		;
	CString strValue	;
	int		iEntry		= 0;
	int		iEntries	= 0;
		
	//
	//	WRITE FIND STRING HISTORY
	//
	iEntries = MIN( this->m_ctrlComboFindWhat.GetCount(), EHistroySize_Persistent_Max );

	pApp->WriteProfileInt( strSection, _T( "FindWhat.Count"	), iEntries	);

	for ( iEntry = 0; iEntry < iEntries; iEntry++ )
	{
		this->m_ctrlComboFindWhat.GetLBText( iEntry, strValue );

		strKey.Format( "FindWhat.%d", iEntry );	

		pApp->WriteProfileString( strSection, strKey, strValue );
	}

	//
	//	WRITE REPLACE STRING HISTORY
	//
	iEntries = MIN( this->m_ctrlComboReplaceWith.GetCount(), EHistroySize_Persistent_Max );

	pApp->WriteProfileInt( strSection, _T( "ReplaceWith.Count" ), iEntries );

	for ( iEntry = 0; iEntry < iEntries; iEntry++ )
	{
		this->m_ctrlComboReplaceWith.GetLBText( iEntry, strValue );	
		
		strKey.Format( "ReplaceWith.%d", iEntry );	
		
		pApp->WriteProfileString( strSection, strKey, strValue );
	}

	//
	//	WRITE DIRECTORY STRING HISTORY
	//
	iEntries = MIN( this->m_ctrlComboDirectory.GetCount(), EHistroySize_Persistent_Max );

	pApp->WriteProfileInt( strSection, _T( "Directory.Count" ), iEntries );

	for ( iEntry = 0; iEntry < iEntries; iEntry++ )
	{
		this->m_ctrlComboDirectory.GetLBText( iEntry, strValue );	
		
		strKey.Format( "Directory.%d", iEntry );	
		
		pApp->WriteProfileString( strSection, strKey, strValue );
	}

	//
	//	RETURN SUCCESS
	//
	return TRUE;
}

//***************************************************************************************************
//**																					 WriteFilters 
//***************************************************************************************************
//**	@DOC		PERSISTENCE
//**	@MFUNC		Saves the dialog's settings to the registry
//**	@RDESC		<t TRUE> if successful, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::WriteFilters( void ) const
{
	//
	//	GET APPLICATION
	//
	CWinApp* pApp = ::AfxGetApp();

	//
	//	LOAD SECTION NAME
	//
	CString strSection; 
			strSection.LoadString( IDS_PROFILE_SECTION );

	//
	//	SETUP VARS
	//
	CString strKey		;
	CString strValue	;
	int		iEntry		= 0;
	int		iEntries	= 0;
		
	//
	//	WRITE FOLDERS
	//
	iEntries = this->m_arrFolders.GetSize();

	pApp->WriteProfileInt( strSection, _T( "Folder.Count" ), iEntries );

	for ( iEntry = 0; iEntry < iEntries; iEntry++ )
	{
		strKey.Format( "Folder.%d.Path"		, iEntry ); pApp->WriteProfileString( strSection, strKey, this->m_arrFolders[ iEntry ].m_strPath  );
		strKey.Format( "Folder.%d.Enabled"	, iEntry ); pApp->WriteProfileInt	( strSection, strKey, this->m_arrFolders[ iEntry ].m_bEnabled );
		strKey.Format( "Folder.%d.Recurse"	, iEntry ); pApp->WriteProfileInt	( strSection, strKey, this->m_arrFolders[ iEntry ].m_bRecurse );
	}

	//
	//	WRITE FILE FILTERS
	//
	iEntries = this->m_arrFileMasks.GetSize();

	pApp->WriteProfileInt( strSection, _T( "FileMask.Count" ), iEntries );

	for ( iEntry = 0; iEntry < iEntries; iEntry++ )
	{
		strKey.Format( "FileMask.%d.Mask"	, iEntry ); pApp->WriteProfileString( strSection, strKey, this->m_arrFileMasks[ iEntry ].m_strMask  );
		strKey.Format( "FileMask.%d.Enabled", iEntry ); pApp->WriteProfileInt	( strSection, strKey, this->m_arrFileMasks[ iEntry ].m_bEnabled );
	}

	//
	//	RETURN SUCCESS
	//
	return TRUE;
}

//
//---------------------------------------------------------------------------------------------------
//*****************************************     HELPERS     *****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																				  GetTextDocument
//***************************************************************************************************
//**	@DOC		HELPERS
//**	@MFUNC		Determines the current text document's interface
//**	@RDESC		A smart pointer to the text document interface
//**	@END
//***************************************************************************************************
//inline
CITextDocument CDialogSmartReplace::GetTextDocument( void )
{
	//
	//	GET ACTIVE DOCUMENT
	//
	CComPtr< IDispatch > pIDispDocument ;

	VERIFY_OK( this->m_pIApplication->get_ActiveDocument( &pIDispDocument ) );

	if ( pIDispDocument.IsEqualObject( NULL ) )
	{
		return NULL;
	}

	//
	//	QUERY TEXT DOCUMENT INTERFACE
	//
	CComQIPtr< ITextDocument, &IID_ITextDocument > pITextDocument( pIDispDocument );

	//
	//	RETURN SMART POINTER
	//
	return pITextDocument;
}

//***************************************************************************************************
//**																				 GetTextSelection
//***************************************************************************************************
//**	@DOC		HELPERS
//**	@MFUNC		Determines the current text selection's interface
//**	@RDESC		A smart pointer to the text selection interface
//**	@END
//***************************************************************************************************
//inline
CITextSelection CDialogSmartReplace::GetTextSelection( void )
{
	//
	//	DELEGATE
	//
	return this->GetTextDocument().GetTextSelection();
}

//***************************************************************************************************
//**																					 GetFindFlags
//***************************************************************************************************
//**	@DOC		HELPERS
//**	@MFUNC		Determines the find flags for the current settings
//**	@RDESC		The find flags
//**	@END
//***************************************************************************************************
//inline
DWORD CDialogSmartReplace::GetFindFlags( void ) const
{
	//
	//	CONCATENATE FLAGS
	//
	return	(									dsMatchForward 
		|	( this->m_bMatchCase			?	dsMatchCase			: 0					)
		|	( this->m_bWholeWord 			?	dsMatchWord   		: 0					)
		|	( this->m_bRegularExpression	?	dsMatchRegExp		: dsMatchNoRegExp	) 
	//	|	( this->m_bRegularExpression	?	dsMatchRegExpCur	: dsMatchNoRegExp	)				// use current RegExp settings
			);
}

//***************************************************************************************************
//**																				  AskSaveAndClose
//***************************************************************************************************
//**	@DOC		HELPERS
//**	@MFUNC		Asks permission to save and close the current document's window
//**	@RDESC		<t TRUE> if permission is granted, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::AskSaveAndClose( void )
{
	//
	//	PRE-SET ABORT FLAG
	//
	this->m_bAborted = FALSE;

	//
	//	CHECK USER OVERRIDE
	//
	if ( ESaveAndClose_Always == this->m_enuSaveAndClose )
	{
		return TRUE;
	}

	if ( ESaveAndClose_Never == this->m_enuSaveAndClose )
	{
		return FALSE;
	}

	//
	//	ASK PERMISSION
	//
	return IDYES == this->MessageBox( _T( "Do you want to save and close this document?" ), _T( "SmartReplace" ), MB_YESNO | MB_ICONQUESTION );
}

//***************************************************************************************************
//**																					AskPermission
//***************************************************************************************************
//**	@DOC		HELPERS
//**	@MFUNC		Asks permission to replace the specified item
//**				replace string using current members' settings 
//**	@PARM		[in] The item to ask permission for
//**	@PARM		[in] The item's name
//**	@PARM		[out] A flag indicating whether the users wishes to abort the replace operation
//**	@RDESC		<t TRUE> if permission is granted, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::AskPermission( EReplaceItem a_enuItem, const CString& a_strName )
{
	//
	//	PRE-SET ABORT FLAG
	//
	this->m_bAborted = FALSE;

	//
	//	QUICK CHECK
	//
	if ( FALSE == this->m_bAskPermission )
	{
		return TRUE;
	}

	if ( EConfirm_Never == this->m_enuConfirmReplacement ) 
	{
		return TRUE;
	}

	//
	//	CHECK ITEM TYPE
	//
	BOOL	bAsk		= FALSE;
	CString strMessage	;

	switch ( a_enuItem )
	{
										//
										//	INSTANCE
										//
		case EReplaceItem_Instance	:	if ( this->m_enuConfirmReplacement == EConfirm_EachInstance ) 
										{
											strMessage	= "Do you want to replace this instance?";
											bAsk		= TRUE;
										}
										break;

										//
										//	FILE
										//
		case EReplaceItem_File		:	if ( this->m_enuConfirmReplacement == EConfirm_EachFile ) 
										{
											strMessage	= "Do you want to replace all instances in file '" + a_strName + "' ?";
											bAsk		= TRUE;
										}
										break;

										//
										//	PROJECT
										//
		case EReplaceItem_Project	:	if ( this->m_enuConfirmReplacement == EConfirm_EachProject ) 
										{
											strMessage	= "Do you want to replace all instances in project '" + a_strName + "' ?";
											bAsk		= TRUE;
										}
										break;
	}

	//
	//	CHECK NECCESSITY
	//
	if ( FALSE == bAsk )
	{
		return TRUE;
	}

	//
	//	DISPLAY DIALOG
	//
	UINT idAnswer = this->MessageBox( strMessage, _T( "SmartReplace" ), MB_YESNOCANCEL | MB_ICONQUESTION );

	//
	//	CHECK RESULT
	//
	if ( IDYES != idAnswer )
	{
		if ( IDCANCEL == idAnswer )
		{
			this->m_bAborted = TRUE;
		}

		return FALSE;
	}

	//
	//	PERMISSION GRANTED
	//
	return TRUE;
}

//***************************************************************************************************
//**																						  AddText
//***************************************************************************************************
//**	@DOC		HELPERS
//**	@MFUNC		Adds the specified text to the specified combo box
//**	@PARM		[in] The combo box
//**	@PARM		[in] The text to add
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::AddText( CComboBox& a_ctrlCombo, const CString& a_strText )
{
	CString strText;
			
	a_ctrlCombo.GetWindowText( strText );
	a_ctrlCombo.SetWindowText( strText + a_strText );
}

//
//---------------------------------------------------------------------------------------------------
//*****************************************     UPDATE     ******************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																				   UpdateControls
//***************************************************************************************************
//**	@DOC		UPDATE
//**	@MFUNC		Updates control's enabled/disabled states according to member vars
//**	@DEVNOTE	The method does _not_ update the member vars prior to modifying the controls.
//**				That's within the caller's responsibility
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::UpdateControls( void )
{
	//
	//	DETERMINE RELEVANT MODES
	//
	BOOL bSelection	= ( EReplaceWhere_Selection			== this->m_iReplaceWhere	);
	BOOL bContinue	= ( EReplaceWhere_File				== this->m_iReplaceWhere	);
	BOOL bExtended	= ( EReplaceWhere_Extended			== this->m_iReplaceWhere	);
	BOOL bDirectory	= ( EReplaceWhereEx_AllInDirectory	== this->m_iReplaceWhereEx	);
	BOOL bFilters	= ( EReplaceWhereEx_AllInFilters	== this->m_iReplaceWhereEx	);

		 bDirectory &= bExtended;
		 bFilters   &= bExtended;

	//
	//	SET DEFAULT CONTROL
	//
	this->SetDefID	( bExtended ? IDC_ADVANCED : IDC_CONTINUE );

	//
	//	ENABLE/DISABLE CONTROLS
	//
	this->GetDlgItem( IDC_CONTINUE						)->EnableWindow(			bContinue			);		// cannot continue in either selection or extended replace modes
	this->GetDlgItem( IDC_REPLACE						)->EnableWindow(			bContinue			);		// cannot continue in either selection or extended replace modes
	this->GetDlgItem( IDC_CHECK_ALL_CASES				)->EnableWindow(	this->m_bMatchCase			);		// only enable when case sensitivity is enabled
	this->GetDlgItem( IDC_COMBO_REPLACE_WHERE			)->EnableWindow(			bExtended			);		// only enable when "extended" is selected
	this->GetDlgItem( IDC_COMBO_EXTENSIONS				)->EnableWindow(			bDirectory			);		// only enable when "in directories" is selected
	this->GetDlgItem( IDC_COMBO_DIRECTORY				)->EnableWindow(			bDirectory			);		// only enable when "in directories" is selected
	this->GetDlgItem( IDC_BROWSE_DIRECTORY				)->EnableWindow(			bDirectory			);		// only enable when "in directories" is selected
	this->GetDlgItem( IDC_CHECK_RECURSE					)->EnableWindow(			bDirectory			);		// only enable when "in directories" is selected
	this->GetDlgItem( IDC_FILTERS						)->EnableWindow(			bFilters			);		// only enable when "in filters" is selected

	this->GetDlgItem( IDC_CONTEXT_MENU_REG_EXP_FIND		)->EnableWindow(	this->m_bRegularExpression	);		// only enable when "regular expression" is selected
	this->GetDlgItem( IDC_CONTEXT_MENU_REG_EXP_REPLACE	)->EnableWindow(	this->m_bRegularExpression	);		// only enable when "regular expression" is selected

	//
	//	DISABLE NON-FUNCTIONALS
	//
	this->GetDlgItem( IDC_CHECK_WHOLE_WORDS				)->EnableWindow( FALSE ==	bSelection			);		// not yet implemented
	this->GetDlgItem( IDC_CHECK_REGULAR_EXPRESSION		)->EnableWindow( FALSE ==	bSelection			);		// not yet implemented
}

//***************************************************************************************************
//**																			   UpdateFindStringEx
//***************************************************************************************************
//**	@DOC		UPDATE
//**	@MFUNC		Updates the find string based on the current mode an the current selected text
//**	@COMM		Calls <mf UpdateFindString>. Then, if the find string still is empty, tries
//**				to reactivate a find string from the history
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::UpdateFindStringEx( void )
{
	//
	//	UPDATE THE FIND STRING
	//
	this->UpdateFindString();

	//
	//	IF EMPTY
	//
	if ( TRUE == this->m_strFindWhat.IsEmpty() )
	{
		//
		//	USE LATEST HISTORY ENTRY
		//
		if ( this->m_ctrlComboFindWhat.GetCount() > 0 )
		{
			this->m_ctrlComboFindWhat.SetCurSel( 0 );
			this->m_ctrlComboFindWhat.GetLBText( 0, this->m_strFindWhat );
		}
	}
}

//***************************************************************************************************
//**																				 UpdateFindString
//***************************************************************************************************
//**	@DOC		UPDATE
//**	@MFUNC		Updates the find string based on the current mode an the current selected text
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::UpdateFindString( void )
{
	//
	//	CURRENT SELECTION DOES NOT MATCH
	//
	this->m_bSelectionMatches = FALSE;

	//
	//	CHECK NECCESSITY
	//
	if ( EFindStringMode_Keep == this->m_enuFindStringMode )
	{
		return;
	}

	//
	//	GET TEXT 
	//
	CString	strText = this->GetTextSelection().GetText();	

	//
	//	We cannot implement the complex behaviour of the standard replace-dialog here
	//	because the ITextSelection interface does not offer all the neccessary methods.
	//	DevStudio uses the line underneath the cursor as search string. 
	//	The line is stripped left and right and tested for emptiness.
	//	If empty, the topmost history item is used.
	//	The ITextSelection however does not allow to determine the line beneath the
	//	cursor without cancelling the current selection.
	//	
	//	So, we implement a "close to usual" strategy.
	//	If there is more than one line selected, we simply disregard the selected text.
	//
	int			iPos		= strText.Find( '\n' );

	if ( iPos >= 0 )							// at least one line
	{
		if ( strText.GetLength() >= iPos + 1 )	// there is more text after the first line
		{
			strText = "";						// disregard the text
		}
	}

	strText.TrimRight( "\r\n" );				// strip off terminators to the right

	//
	//	CHECK FOR EMPTY
	//
/*	if ( strText.IsEmpty() )
	{
		//
		//	CHECK MODE
		//
		switch ( this->m_enuFindStringMode )
		{
			case EFindStringMode_KeepIfNoSelection:	return;
		}

		//
		//	SELECT CURRENT LINE
		//
	//	VERIFY_OK( pITextSelection->SelectLine	() );			// we're only interested in one line
	//	VERIFY_OK( pITextSelection->get_Text	( &bszText ) );
	//	VERIFY_OK( pITextSelection->Cancel		() );

	//	strText = bszText;
	//	strText.TrimRight( "\r\n" );
	}
*/

	//
	//	CURRENT SELECTION MATCHES IF FIND STRING IS NOT EMPTY
	//
	this->m_bSelectionMatches = strText.IsEmpty() ? FALSE : TRUE;

	//
	//	SET TEXT
	//
	this->m_strFindWhat = strText;

	//
	//	UPDATE CONTROLS FROM MEMBERS
	//
	this->UpdateData( EUpdateData_ToControls );
}

//***************************************************************************************************
//**																				   UpdateAdvanced
//***************************************************************************************************
//**	@DOC		UPDATE
//**	@MFUNC		Shows/hides advanced options' controls
//**	@PARM		[in] The caption of the button to go to
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::UpdateAdvanced( const CString& a_strCaptionTo )
{
	//
	//	GET CURRENT CAPTION
	//
	CString strCaption; this->m_ctrlBtnAdvanced.GetWindowText( strCaption );

	//
	//	COMPRE CAPTIONS
	//
	if ( a_strCaptionTo == strCaption )
	{
		return;
	}

	//
	//	TOGGLE MODE
	//
	this->OnAdvanced();
}

//***************************************************************************************************
//**																				  UpdateHistories
//***************************************************************************************************
//**	@DOC		UPDATE
//**	@MFUNC		Updates the combo boxes' histories
//**	@COMM		The user is responsible for calling <mf UpdateData>.
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::UpdateHistories( void )
{
	this->UpdateHistoryFind		();
	this->UpdateHistoryReplace	();
	this->UpdateHistoryDirectory();
}

//***************************************************************************************************
//**																				UpdateHistoryFind
//***************************************************************************************************
//**	@DOC		UPDATE
//**	@MFUNC		Updates the find string combo box' history
//**	@COMM		The user is responsible for calling <mf UpdateData>.
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::UpdateHistoryFind( void )
{
	//
	//	DO NOT INSERT EMPTY STRINGS
	//
	if ( TRUE == this->m_strFindWhat.IsEmpty() )
	{
		return;
	}

	//
	//	DO NOT DUPLICATE	[ sadly, CComboBox::FindStringExact ignores the case, so we have to search ourselves ]
	//
	CString strText	;
	int		iItem	= 0;
	BOOL	bFound	= FALSE;

	for ( iItem = 0; iItem < this->m_ctrlComboFindWhat.GetCount(); iItem++ )
	{
		//
		//	GET TEXT
		//
		this->m_ctrlComboFindWhat.GetLBText( iItem, strText );

		//
		//	SKIP MISMATCHES
		//
		if ( 0 != strText.Compare( this->m_strFindWhat ) )
		{
			continue;
		}

		//
		//	MATCH
		//
		bFound = TRUE;

		break;
	}

	//
	//	CHECK RESULT
	//
	if ( TRUE == bFound )
	{
		//
		//	REMOVE DUPLICATE
		//
		this->m_ctrlComboFindWhat.DeleteString( iItem );
	}

	//
	//	PLACE FIND STRING ON TOP
	//
	this->m_ctrlComboFindWhat.InsertString( 0, this->m_strFindWhat );

	//
	//	RE-SELECT THE ITEM
	//
	this->m_ctrlComboFindWhat.SetCurSel( 0 );
}

//***************************************************************************************************
//**																			 UpdateHistoryReplace
//***************************************************************************************************
//**	@DOC		UPDATE
//**	@MFUNC		Updates the replace string combo box' history
//**	@COMM		The user is responsible for calling <mf UpdateData>.
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::UpdateHistoryReplace( void )
{
	//
	//	DO NOT INSERT EMPTY STRINGS
	//
	if ( TRUE == this->m_strReplaceWith.IsEmpty() )
	{
		return;
	}

	//
	//	DO NOT DUPLICATE	[ sadly, CComboBox::FindStringExact ignores the case, so we have to search ourselves ]
	//
	CString strText	;
	int		iItem	= 0;
	BOOL	bFound	= FALSE;

	for ( iItem = 0; iItem < this->m_ctrlComboReplaceWith.GetCount(); iItem++ )
	{
		//
		//	GET TEXT
		//
		this->m_ctrlComboReplaceWith.GetLBText( iItem, strText );

		//
		//	SKIP MISMATCHES
		//
		if ( 0 != strText.Compare( this->m_strReplaceWith ) )
		{
			continue;
		}

		//
		//	MATCH
		//
		bFound = TRUE;

		break;
	}

	//
	//	CHECK RESULT
	//
	if ( TRUE == bFound )
	{
		//
		//	REMOVE DUPLICATE
		//
		this->m_ctrlComboReplaceWith.DeleteString( iItem );
	}

	//
	//	INSERT REPLACE STRING ON TOP
	//
	this->m_ctrlComboReplaceWith.InsertString( 0, this->m_strReplaceWith );

	//
	//	RE-SELECT THE ITEM
	//
	this->m_ctrlComboReplaceWith.SetCurSel( 0 );
}

//***************************************************************************************************
//**																		   UpdateHistoryDirectory
//***************************************************************************************************
//**	@DOC		UPDATE
//**	@MFUNC		Updates the directory string combo box' history
//**	@COMM		The user is responsible for calling <mf UpdateData>.
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::UpdateHistoryDirectory( void )
{
	//
	//	DO NOT INSERT EMPTY STRINGS
	//
	if ( TRUE == this->m_strDirectory.IsEmpty() )
	{
		return;
	}

	//
	//	DO NOT DUPLICATE	[ sadly, CComboBox::FindStringExact ignores the case, so we have to search ourselves ]
	//
	CString strText	;
	int		iItem	= 0;
	BOOL	bFound	= FALSE;

	for ( iItem = 0; iItem < this->m_ctrlComboDirectory.GetCount(); iItem++ )
	{
		//
		//	GET TEXT
		//
		this->m_ctrlComboDirectory.GetLBText( iItem, strText );

		//
		//	SKIP MISMATCHES
		//
		if ( 0 != strText.Compare( this->m_strDirectory ) )
		{
			continue;
		}

		//
		//	MATCH
		//
		bFound = TRUE;

		break;
	}

	//
	//	CHECK RESULT
	//
	if ( TRUE == bFound )
	{
		//
		//	REMOVE DUPLICATE
		//
		this->m_ctrlComboDirectory.DeleteString( iItem );
	}

	//
	//	INSERT DIRECTORY STRING ON TOP
	//
	this->m_ctrlComboDirectory.InsertString( 0, this->m_strDirectory );

	//
	//	RE-SELECT THE ITEM
	//
	this->m_ctrlComboDirectory.SetCurSel( 0 );
}

//
//---------------------------------------------------------------------------------------------------
//*****************************************     REPLACE     *****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																						 FindText
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Finds the next matching text
//**	@RDESC		<t TRUE> if a match has been found, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::FindText( void )
{
	return this->FindTextEx( this->m_strFindWhat, this->GetFindFlags(), this->m_bAllCases );
}

//***************************************************************************************************
//**																					  ReplaceNext
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces the current matching text
//**	@RDESC		<t TRUE> if a replacement has been made, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::ReplaceNext( void )
{
	//
	//	DELEGATE
	//
	return this->ReplaceStepEx( this->m_strFindWhat, this->m_strReplaceWith, this->GetFindFlags(), this->m_bAllCases );
}

//***************************************************************************************************
//**																					   ReplaceAll
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string with the replace string using 
//**				current members' settings.
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAll( void )
{
	//
	//	CLEAR FOUND MATCHES
	//
	this->ResetMatches();

	//
	//	CHECK AVAILABILITY
	//
	if ( FALSE == this->GetTextSelection().IsValid() )
	{
		return 0;
	}

	//
	//	REPLACE ALL
	//
	int iReplaced = 0;

	while ( TRUE == this->ReplaceNext() )	
	{
		//
		//	INCREASE COUNT
		//
		++iReplaced;	

		//
		//	CHECK FOR ABORTION
		//
		if ( TRUE == this->m_bAborted )
		{
			return iReplaced;
		}

		//
		//	CHECK FOR FILE FINISHED
		//
		if ( TRUE == this->m_bFileFinished )
		{
			return iReplaced;
		}
	}

	//
	//	RETURN NUMBER OF REPLACEMENTS
	//
	return iReplaced;
}

//***************************************************************************************************
//**																			  ReplaceAllSelection
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string in the current selection with the 
//**				replace string using current members' settings 
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAllSelection( void )
{
	//
	//	GET TEXT SELECTION
	//
	CITextSelection pITextSelection = this->GetTextSelection();

	if ( FALSE == pITextSelection.IsValid() )
	{
		return 0;
	}

	//
	//	GET TEXT
	//
	CStringEx	strText		= pITextSelection.GetText();
	int			iReplaced	= 0;

	//
	//	REPLACE IN TEXT
	//
	DWORD dwFlags	= this->m_bWholeWord 	? CStringEx::EMatchFlag_Word		: 0
					| this->m_bMatchCase	? CStringEx::EMatchFlag_Case		: 0
					| this->m_bAllCases		? CStringEx::EMatchFlag_AllCases	: 0;

	iReplaced = strText.ReplaceEx( this->m_strFindWhat, this->m_strReplaceWith, dwFlags );

	//
	//	SET TEXT
	//
	pITextSelection.SetText( strText );

	//
	//	RETURN COUNT
	//
	return iReplaced;
}

//***************************************************************************************************
//**																				   ReplaceAllOpen
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string in all open text files with the 
//**				replace string using current members' settings 
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAllOpen( void )
{
	//
	//	ITERATE TEXT WINDOWS
	//
	int		iReplaced	= 0;
	long	lWindows	= this->m_pIApplication.GetWindows().GetCount();

	for ( long lWindow = 1; lWindow <= lWindows; lWindow++ ) // indices are 1-based (VB-style?)
	{
		//
		//	GET TEXT WINDOW
		//
		CITextWindow pITextWindow = this->m_pIApplication.GetWindows().GetItem( lWindow );

		if ( FALSE == pITextWindow.IsValid() )
		{
			continue;	// not a text window
		}

		//
		//	ACTIVATE THE WINDOW
		//
		pITextWindow->put_Active( VARIANT_TRUE );

		//
		//	ASK PERMISSION
		//
		if ( FALSE == this->AskPermission( EReplaceItem_File, pITextWindow.GetTextDocument().GetGenericDocument().GetFullName() ) )
		{
			if ( TRUE == this->m_bAborted )
			{
				break;
			}
			else
			{
				continue;
			}
		}

		//
		//	YEP, REPLACE HERE
		//
		iReplaced += this->ReplaceAll();

		//
		//	RE-CHECK ABORT FLAG
		//
		if ( TRUE == this->m_bAborted )
		{
			break;
		}
	}

	//
	//	RETURN REPLACEMENT COUNT
	//
	return iReplaced;
}

//***************************************************************************************************
//**																				ReplaceAllProject
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string in all project text files with the 
//**				replace string using current members' settings 
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAllProject( void )
{
	//
	//	DELEGATE
	//
	return this->ReplaceAllProject( this->m_pIApplication.GetActiveProject() );
}

//***************************************************************************************************
//**																			  ReplaceAllWorkspace
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string in all workspace text files with the 
//**				replace string using current members' settings 
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAllWorkspace( void )
{
	//
	//	REPLACE IN ALL PROJECTS
	//
	CIProjects	pIProjects	= this->m_pIApplication.GetProjects();
	long		lProjects	= pIProjects.GetCount();
	int			iReplaced	= 0;

	for ( long lProject = 0; lProject < lProjects; lProject++ )
	{
		//
		//	ASK PERMISSION
		//
		if ( FALSE == this->AskPermission( EReplaceItem_Project, pIProjects[ lProject ].GetName() ) )
		{
			if ( TRUE == this->m_bAborted )
			{
				break;
			}
			else
			{
				continue;
			}
		}

		//
		//	REPLACE IN THIS PROJECT
		//
		iReplaced += this->ReplaceAllProject( pIProjects[ lProject ] );

		//
		//	RE-CHECK ABORT FLAG
		//
		if ( TRUE == this->m_bAborted )
		{
			break;
		}
	}

	//
	//	RETURN COUNT
	//
	return iReplaced;
}

//***************************************************************************************************
//**																			  ReplaceAllDirectory
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string in all text files in specified
//**				directory and file filter
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAllDirectory( void )
{
	//
	//	DELEGATE
	//
	return this->ReplaceAllDirectoryEx( this->m_strDirectory, this->m_strExtensions, this->m_bRecurse );
}

//***************************************************************************************************
//**																				ReplaceAllFilters
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string in all text files matching filters 
//**				with the replace string using current members' settings 
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAllFilters( void )
{
	//
	//	SETUP RESULT
	//
	int iReplaced = 0;

	//
	//	ENUMERATE FOLDERS
	//
	for ( int iFolder = 0; iFolder < this->m_arrFolders.GetSize(); iFolder++ )
	{
		//
		//	GET FOLDER
		//
		const CFolder& folder = this->m_arrFolders[ iFolder ];

		if ( FALSE == folder.m_bEnabled )
		{
			continue;
		}

		//
		//	ENUMERATE FILE MASKS
		//
		for ( int iFileMask = 0; iFileMask < this->m_arrFileMasks.GetSize(); iFileMask++ )
		{
			//
			//	GET FILE MASK
			//
			const CFileMask& mask = this->m_arrFileMasks[ iFileMask ];

			if ( FALSE == mask.m_bEnabled )
			{
				continue;
			}

			//
			//	REPLACE IN THIS PAIR
			//
			iReplaced += this->ReplaceAllDirectoryEx( folder.m_strPath, mask.m_strMask, folder.m_bRecurse );

			//
			//	CHECK FOR ABORTION
			//
			if ( this->m_bAborted )
			{
				return iReplaced;
			}
		}
	}

	//
	//	RETURN RESULT
	//
	return iReplaced;
}

//***************************************************************************************************
//**																						 FindText   
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Finds (and marks) the next occurance of the specified text
//**	@PARM		[in] The text to find
//**	@PARM		[in] The options (a combination of <t DsTextSearchOptions> flags)
//**	@RDESC		<t TRUE> if successful, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::FindText( const CString& a_strFind, DWORD a_dwFlags ) 
{
	//
	//	FIND THE TEXT
	//
	this->m_bSelectionMatches = this->GetTextSelection().FindText( a_strFind, a_dwFlags );

	//
	//	GET POSITION
	//
	CSelectionPos pos;

	pos.m_lLine		=	this->GetTextSelection().GetCurrentLine	 ();
	pos.m_lColumn	=	this->GetTextSelection().GetCurrentColumn();
	
	//
	//	CHECK IF THIS POSITION HAS ALREADY BEEN FOUND
	//
	this->m_bFileFinished = FALSE;

	for ( int iPos = 0; iPos < this->m_arrFoundMatches.GetSize(); iPos++ )
	{
		if ( pos == this->m_arrFoundMatches[ iPos ] )
		{
			//
			//	FINISHED THIS FILE
			//
			this->m_bFileFinished = TRUE;

			return this->m_bSelectionMatches;
		}
	}

	//
	//	ADD TO MATCH POSITIONS
	//
	this->m_arrFoundMatches.Add( pos );

	//
	//	RETURN RESULT
	//
	return this->m_bSelectionMatches;
}

//***************************************************************************************************
//**																					   FindTextEx
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Finds (and marks) the next occurance of the specified text
//**	@PARM		[in] The text to find
//**	@PARM		[in] The options (a combination of <t DsTextSearchOptions> flags)
//**	@PARM		[in] A falg indicatin whether to check for all cases
//**	@RDESC		<t TRUE> if successful, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::FindTextEx( const CString& a_strFind, DWORD a_dwFlags, BOOL a_bAllCases ) 
{
	//
	//	DO AS-IS FIND STEP
	//
	this->m_enuCase = ECase_AsIs;

	CString strFind( a_strFind );

	if ( TRUE == this->FindText( strFind, a_dwFlags ) )
	{
		//
		//	CHECK FOR END
		//
		if ( FALSE == this->m_bFileFinished )		// there may be more matches for the same case in this file
		{
			return TRUE;							
		}

		//
		//	NO MORE OCCURANCES OF THIS CASE IN THE FILE
		//
		if ( FALSE == a_bAllCases )					// this file is through and we do not have to check more cases
		{
			return TRUE;
		}

		//
		//	RESET FILE END FLAG
		//
		this->m_bFileFinished = FALSE;
	}
	else
	{
		//
		//	NO MATCH FOUND
		//
		if ( FALSE == a_bAllCases )					// no more cases to handle
		{
			return FALSE;
		}
	}

	//
	//	DO LOWER CASE FIND STEP
	//
	this->m_enuCase = ECase_Lower;

	strFind.MakeLower();

	if ( strFind != a_strFind )
	{
		if ( TRUE == this->FindText( strFind, a_dwFlags ) )
		{
			//
			//	CHECK FOR END
			//
			if ( FALSE == this->m_bFileFinished )		// there may be more matches for the same case in this file
			{
				return TRUE;							
			}

			//
			//	NO MORE OCCURANCES OF THIS CASE IN THE FILE
			//
			this->m_bFileFinished = FALSE;
		}
	}

	//
	//	DO UPPER CASE FIND STEP
	//
	this->m_enuCase = ECase_Upper;

	strFind.MakeUpper();

	if ( strFind != a_strFind )
	{
		if ( TRUE == this->FindText( strFind, a_dwFlags ) )
		{
			return TRUE;
		}
	}

	//
	//	RESTORE CASE
	//
	this->m_enuCase = ECase_AsIs;

	//
	//	NO MATCH
	//
	return FALSE;
}

//***************************************************************************************************
//**																					  ReplaceStep
//***************************************************************************************************
//**	@DOC		EXTENSIONS
//**	@MFUNC		Performs one replace step. See comment for more details.
//**	@PARM		[in] The text to find
//**	@PARM		[in] The text to replace with
//**	@PARM		[in] The options (a combination of <t DsTextSearchOptions> flags)
//**	@RDESC		<t FALSE> if there are no more occurances or the search string, <t TRUE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::ReplaceStep( const CString& a_strFind, const CString& a_strReplace, DWORD a_dwFlags ) 
{
	//
	//	DELEGATE
	//
	return this->ReplaceStepEx( a_strFind, a_strReplace, a_dwFlags, FALSE );
}

//***************************************************************************************************
//**																					  ReplaceStep
//***************************************************************************************************
//**	@DOC		EXTENSIONS
//**	@MFUNC		Performs one replace step. See comment for more details.
//**	@PARM		[in] The text to find
//**	@PARM		[in] The text to replace with
//**	@PARM		[in] The options (a combination of <t DsTextSearchOptions> flags)
//**	@PARM		[in] A flag indicating whether to replace all cases when using case matching.
//**				<nl> For instance: If the search string is "Test" and th replace string is "Temp"
//**									then "Test" will be replaced with "Temp", 
//**										 "test" will be replaced with "temp"
//**									and  "TEST" will be replaced with "TEST"
//**									but  "tEst" will not be replaced.
//**	@RDESC		<t FALSE> if there are no more occurances or the search string, <t TRUE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::ReplaceStepEx( const CString& a_strFind, const CString& a_strReplace, DWORD a_dwFlags, BOOL a_bAllCases ) 
{
	//
	//	GET TEXT SELECTION
	//
	CITextSelection pITextSelection = this->GetTextSelection();

	if ( FALSE == pITextSelection.IsValid() )
	{
		return FALSE;
	}

	//
	//	CHECK SELECTION FOR MATCH
	//
	if ( TRUE == this->m_bSelectionMatches )
	{
		//
		//	ASK PERMISSION
		//
		if ( TRUE == this->AskPermission( EReplaceItem_Instance, "" ) )
		{
			//
			//	SETUP REPLACE TEXT
			//
			CString strReplace( a_strReplace );

			//
			//	CHECK CASE
			//
			switch ( this->m_enuCase )
			{
				case ECase_Lower:	strReplace.MakeLower();	break;
				case ECase_Upper:	strReplace.MakeUpper();	break;
			}

			//
			//	REPLACE TEXT
			//
			pITextSelection.SetText( strReplace );
		}

		//
		//	CHECK FOR ABORT
		//
		if ( TRUE == this->m_bAborted )
		{
			return FALSE;
		}
	}

	//
	//	FIND NEXT OCCURANCE
	//
	return this->FindTextEx( a_strFind, a_dwFlags, a_bAllCases );
}

//***************************************************************************************************
//**																				   ReplaceAllFile
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string in all specified file with the 
//**				replace string using current members' settings 
//**	@PARM		[in] The file to replace in
//**	@PARM		[in] A flag indicating whether to forcedly open the file in text mode
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAllFile( const CString& a_strFile, BOOL a_bText /*= FALSE*/ )
{
	//
	//	SETUP VARS
	//
	CIDocuments	pIDocuments		= this->m_pIApplication.GetDocuments();	if ( FALSE == pIDocuments.IsValid() ) { return 0; }
	int			iReplaced		= 0;

	//
	//	TRY TO FIND AN ALREADY OPEN DOCUMENT OF THAT FILE
	//
	CIGenericDocument	pIGenericDocument	= pIDocuments.FindByFullName( a_strFile );
	BOOL				bOpenAlready		= pIGenericDocument.IsValid();

	//
	//	OPEN THE FILE AS A GENERIC DOCUMENT
	//
	pIGenericDocument = pIDocuments.Open( a_strFile, a_bText ? "Text" : "Auto", FALSE );	

	if ( FALSE == pIGenericDocument.IsValid() )
	{
		return 0;
	}

	//
	//	CHECK WHETER IT IS A TEXT DOCUMENT
	//
	CITextDocument pITextDocument = pIGenericDocument;		

	if ( FALSE == pITextDocument.IsValid() )
	{
		//
		//	NO TEXT DOCUMENT - CLOSE IT
		//
		pIGenericDocument.Close( FALSE );

		//
		//	AND SKIP IT
		//
		return 0;
	}

	//
	//	ASK PERMISSION
	//
	if ( FALSE == this->AskPermission( EReplaceItem_File, a_strFile ) )
	{
		//
		//	Closing the document is too dangerous: when closing it with bSave = FALSE, the method 
		//	simply fails due to no apparent reason (maybe has something to do with the doc's ref-count). 
		//	On the other hand, we cannot simply save the document because when it has already been opened
		//	and edit by the user his modifications would be lost ...
		//
		//	A reasonable solution consist in scanning the open windows before opening the document. If
		//	there is a window for the document already then, at this point, leave it open:
		//

		//
		//	DO NOT CLOSE DOCUMENTS THAT WERE OPEN 
		//
		if ( FALSE == bOpenAlready )
		{
			//
			//	CLOSE NOT NEEDED DOCUMENT
			//
			pITextDocument	= CITextDocument( NULL );		
			pIGenericDocument.Close( TRUE );			// we just opened it - it's safe to save it ...
		}
		
		//
		//	EXIT WITH RESULT
		//
		return iReplaced;
	}

	//
	//	REPLACE IN THIS DOCUMENT
	//
	iReplaced += this->ReplaceAll();

	//
	//	CHECK FOR ABORTION
	//
	if ( TRUE == this->m_bAborted )
	{
		return iReplaced;
	}

	//
	//	SAVE AND CLOSE THE DOCUMENT
	//
	if ( TRUE == this->AskSaveAndClose() ) 
	{
		pITextDocument	 = CITextDocument( NULL );			
		pIGenericDocument.Close( TRUE );
	}

	//
	//	RETURN NUMBER OF REPLACEMENTS
	//
	return iReplaced;
}

//***************************************************************************************************
//**																				ReplaceAllProject
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string in all project text files with the 
//**				replace string using current members' settings 
//**	@PARM		[in] The project to replace in
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAllProject( CIGenericProject a_pIProject )
{
	//
	//	CHECK VALIDITY
	//
	if ( FALSE == a_pIProject.IsValid() )
	{
		return 0;
	}

	//
	//	SETUP VARS
	//
	CIDocuments	pIDocuments = this->m_pIApplication.GetDocuments	();	if ( FALSE == pIDocuments	.IsValid() )	{	return 0;	}
	int			iReplaced	= 0;

	//
	//	GET FILES IN ACTIVE PROJECT
	//
	CArray< CString, CString& > arrPaths;

	a_pIProject.GetSourceFilePaths( arrPaths );

	//
	//	ENUMERATE FILES
	//
	for ( int iFile = 0; iFile < arrPaths.GetSize(); iFile++ )
	{
		//
		//	REPLACE IN FILE
		//
		this->ReplaceAllFile( arrPaths[ iFile ] );

		//
		//	CHECK ABORT FLAG
		//
		if ( TRUE == this->m_bAborted )
		{
			break;
		}
	}

	//
	//	RETURN COUNT
	//
	return iReplaced;
}

//***************************************************************************************************
//**																			  ReplaceAllDirectory
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string in all specified directory
//**	@PARM		[in] The directory to replace in
//**	@PARM		[in] The file filter
//**	@PARM		[in] A flag indicating whether to recurse sub-directories
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAllDirectory( const CString& a_strDirectory, const CString& a_strFilter, BOOL a_bRecurse )
{
	//
	//	SETUP RESULT
	//
	int iReplaced = 0;

	//
	//	FIX PATH
	//
	CString strDirectory( a_strDirectory );

	if (	( strDirectory.Right( 1 ) != '\\' ) 
		 && ( strDirectory.Right( 1 ) != '/'  )  )
	{
		strDirectory += "/";
	}

	//
	//	FIND FILES
	//
	CFileFind	finder		;
	BOOL		bContinue	= finder.FindFile( strDirectory + a_strFilter );

	while ( TRUE == bContinue )
	{
		//
		//	CHECK ABORT FLAG
		//
		if ( TRUE == this->m_bAborted )
		{
			return iReplaced;
		}

		//
		//	FIND NEXT FILE
		//
		bContinue = finder.FindNextFile();

		//
		//	CHECK FOR DOTS
		//
		if ( TRUE == finder.IsDots() )
		{
			continue;
		}

		//
		//	CHECK FOR DIRECTORY
		//
		if ( TRUE == finder.IsDirectory() )
		{
			//
			//	CHECK RECURSE FLAG
			//
			if ( TRUE == a_bRecurse )
			{
				//
				//	ONLY RECURSE WHEN ENUMERATING ALL FILES
				//
				if ( "*.*" == a_strFilter )
				{
					//
					//	RECURSE
					//
					iReplaced += this->ReplaceAllDirectory( finder.GetFilePath(), a_strFilter, a_bRecurse );
				}
				else
				{
					continue;
				}
			}
			else
			{
				//
				//	SKIP DIRECTORIES
				//
				continue;
			}
		}

		//
		//	REPLACE IN THIS FILE
		//
		iReplaced += this->ReplaceAllFile( finder.GetFilePath(), TRUE );	// force open as text file
	}

	//
	//	CHECK FILTER
	//
	if ( "*.*" != a_strFilter )
	{
		//
		//	CHECK FOR RECURSION
		//
		if ( TRUE == a_bRecurse )
		{
			//
			//	ENUMERATE DIRECTORIES MANUALLY
			//
			CFileFind	finder		;
			BOOL		bContinue	= finder.FindFile( strDirectory + "*.*" );

			while ( TRUE == bContinue )
			{
				//
				//	CHECK ABORT FLAG
				//
				if ( TRUE == this->m_bAborted )
				{
					return iReplaced;
				}
			
				//
				//	FIND NEXT FILE
				//
				bContinue = finder.FindNextFile();

				//
				//	CHECK FOR DOTS
				//
				if ( TRUE == finder.IsDots() )
				{
					continue;
				}

				//
				//	CHECK FOR DIRECTORY
				//
				if ( TRUE == finder.IsDirectory() )
				{
					//
					//	RECURSE INTO THIS DIRECTORY
					//
					iReplaced += this->ReplaceAllDirectory( finder.GetFilePath(), a_strFilter, a_bRecurse );
				}
			}
		}
	}

	//
	//	RETURN COUNT
	//
	return iReplaced;
}

//***************************************************************************************************
//**																			ReplaceAllDirectoryEx
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Replaces all occurances of the find string in all specified directory
//**	@PARM		[in] The directory to replace in
//**	@PARM		[in] The file filters
//**	@PARM		[in] A flag indicating whether to recurse sub-directories
//**	@RDESC		The number of replacements made
//**	@END
//***************************************************************************************************
//inline
int CDialogSmartReplace::ReplaceAllDirectoryEx( const CString& a_strDirectory, const CString& a_strExtensions, BOOL a_bRecurse )
{
	//
	//	SETUP RESULT
	//
	int iReplaced = 0;

	//
	//	COLLECT FILTERS
	//
	CArray< CString, CString& > arrFilters;

	CString strLeft		= "";
	CString strRight	= a_strExtensions;
	int		iPos		= a_strExtensions.Find( ';' );

	while ( iPos >= 0 )
	{
		strLeft		= strRight.Left( iPos );
		strRight	= strRight.Right( strRight.GetLength() - iPos - 1 );

		iPos		= strRight.Find( ';' );

		strLeft.TrimLeft ();
		strLeft.TrimRight();

		arrFilters.Add( strLeft );
	}

	if ( FALSE == strRight.IsEmpty() )
	{
		strRight.TrimRight();
		strRight.TrimRight();

		arrFilters.Add( strRight );
	}

	//
	//	ENUMERATE FILTERS
	//
	for ( int iFilter = 0; iFilter < arrFilters.GetSize(); iFilter++ )
	{
		//
		//	DELEGATE 
		//
		iReplaced += this->ReplaceAllDirectory( a_strDirectory, arrFilters[ iFilter ], a_bRecurse );
	}

	//
	//	RETURN COUNT
	//
	return iReplaced;
}

//***************************************************************************************************
//**																					 ResetMatches
//***************************************************************************************************
//**	@DOC		REPLACE
//**	@MFUNC		Resets matches for the current file
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::ResetMatches( void )
{
	this->m_arrFoundMatches		.RemoveAll();
	this->m_bFileFinished		= FALSE;
	this->m_bSelectionMatches	= FALSE;
}

//
//---------------------------------------------------------------------------------------------------
//****************************************     VIRTUALS     *****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																				   DoDataExchange
//***************************************************************************************************
//**	@DOC		VIRTUALS
//**	@MFUNC		Exchanges data between the dialog's members and its controls
//**	@PARM		[in/out] Pointer to data exchange context
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange( pDX );

	//{{AFX_DATA_MAP(CDialogSmartReplace)
	DDX_Control	( pDX, IDC_COMBO_EXTENSIONS			, m_ctrlComboExtensions		);
	DDX_Control	( pDX, IDC_COMBO_DIRECTORY			, m_ctrlComboDirectory		);
	DDX_Control	( pDX, IDC_COMBO_REPLACE_WITH		, m_ctrlComboReplaceWith	);
	DDX_Control	( pDX, IDC_COMBO_FIND_WHAT			, m_ctrlComboFindWhat		);
	DDX_Control	( pDX, IDC_ADVANCED					, m_ctrlBtnAdvanced			);
	DDX_Check	( pDX, IDC_CHECK_ALL_CASES			, m_bAllCases				);
	DDX_Check	( pDX, IDC_CHECK_MATCH_CASE			, m_bMatchCase				);
	DDX_Check	( pDX, IDC_CHECK_REGULAR_EXPRESSION	, m_bRegularExpression		);
	DDX_Check	( pDX, IDC_CHECK_WHOLE_WORDS		, m_bWholeWord				);
	DDX_CBString( pDX, IDC_COMBO_FIND_WHAT			, m_strFindWhat				);
	DDX_CBString( pDX, IDC_COMBO_REPLACE_WITH		, m_strReplaceWith			);
	DDX_CBIndex	( pDX, IDC_COMBO_REPLACE_WHERE		, m_iReplaceWhereEx			);
	DDX_Radio	( pDX, IDC_RADIO_SELECTION			, m_iReplaceWhere			);
	DDX_CBString( pDX, IDC_COMBO_DIRECTORY			, m_strDirectory			);
	DDX_CBString( pDX, IDC_COMBO_EXTENSIONS			, m_strExtensions			);
	DDX_Check	( pDX, IDC_CHECK_RECURSE			, m_bRecurse				);
	//}}AFX_DATA_MAP
}

//***************************************************************************************************
//**																				 OnSearchComplete
//***************************************************************************************************
//**	@DOC		VIRTUALS
//**	@MFUNC		Called when the search completed and no more matches can be found
//**	@PARM		[in] A flag indicating whether to display a message box stating that there are
//**						no more occurances of the search string
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnSearchComplete( BOOL a_bMessageBox /*= TRUE*/ ) 
{
	//
	//	CANCEL SELECTION
	//
//	this->GetTextSelection().Cancel();

	//
	//	CHECK FOR MESSAGE BOX
	//
	if ( FALSE == a_bMessageBox )
	{
		return;
	}

	//
	//	CHECK FOR ABORTION
	//
	if ( TRUE == this->m_bAborted )
	{
		return;
	}

	//
	//	DISPLAY MESSAGE BOX
	//
	CString strText; 
			strText.Format( "Completed search for '%s'.", this->m_strFindWhat );

	this->MessageBox( strText, _T( "SmartReplace" ), MB_ICONEXCLAMATION );

	//
	//	RESET MATCHES
	//
	this->ResetMatches();
}

//
//---------------------------------------------------------------------------------------------------
//****************************************     MESSAGES     *****************************************
//---------------------------------------------------------------------------------------------------
//

BEGIN_MESSAGE_MAP( CDialogSmartReplace, CDialog )
	//{{AFX_MSG_MAP(CDialogSmartReplace)
	ON_WM_CLOSE		()
	ON_BN_CLICKED	( IDC_CONTINUE						, OnContinue						)
	ON_BN_CLICKED	( IDC_REPLACE						, OnReplace							)
	ON_BN_CLICKED	( IDC_REPLACE_ALL					, OnReplaceAll						)
	ON_BN_CLICKED	( IDC_ADVANCED						, OnAdvanced						)
	ON_BN_CLICKED	( IDC_CHECK_MATCH_CASE				, OnCheckMatchCase					)
	ON_BN_CLICKED	( IDC_CHECK_REGULAR_EXPRESSION		, OnCheckRegularExpression			)
	ON_CBN_SELENDOK	( IDC_COMBO_REPLACE_WHERE			, OnSelEndOkComboReplaceWhere		)
	ON_BN_CLICKED	( IDC_RADIO_SELECTION				, OnRadioSelection					)
	ON_BN_CLICKED	( IDC_RADIO_FILE					, OnRadioFile						)
	ON_BN_CLICKED	( IDC_RADIO_EXTENDED				, OnRadioExtended					)
	ON_BN_CLICKED	( IDC_OPTIONS						, OnOptions							)
	ON_BN_CLICKED	( IDC_DEBUG							, OnDebug							)
	ON_BN_CLICKED	( IDC_FILTERS						, OnFilters							)
	ON_BN_CLICKED	( IDC_BROWSE_DIRECTORY				, OnBrowseDirectory					)
	ON_BN_CLICKED	( IDC_CONTEXT_MENU_REG_EXP_FIND		, OnContextMenuRegExpFind			)
	ON_BN_CLICKED	( IDC_CONTEXT_MENU_REG_EXP_REPLACE	, OnContextMenuRegExpReplace		)
																							
	ON_COMMAND		( ID_OPTIONS_QUOTEDSTRING			, OnCommandQuotedString				)
	ON_COMMAND		( ID_OPTIONS_ANYCHARACTER			, OnCommandAnyChar					)
	ON_COMMAND		( ID_OPTIONS_CHARACTERINRANGE		, OnCommandInRange					)
	ON_COMMAND		( ID_OPTIONS_CHARACTERNOTINRANGE	, OnCommandNotInRange				)
	ON_COMMAND		( ID_OPTIONS_BEGINNINGOFLINE		, OnCommandBeginOfLine				)
	ON_COMMAND		( ID_OPTIONS_ENDOFLINE				, OnCommandEndOfLine				)
	ON_COMMAND		( ID_OPTIONS_TAGGEDEXPRESSION		, OnCommandTaggedExp				)
	ON_COMMAND		( ID_OPTIONS_NOT					, OnCommandNot						)
	ON_COMMAND		( ID_OPTIONS_OR						, OnCommandOr						)
	ON_COMMAND		( ID_OPTIONS_0ORMOREMATCHES			, OnCommand0OrMore					)
	ON_COMMAND		( ID_OPTIONS_1ORMOREMATCHES			, OnCommand1OrMore					)
	ON_COMMAND		( ID_OPTIONS_GROUP					, OnCommandGroup					)
	ON_COMMAND		( ID_OPTIONS_WHITESPACE				, OnCommandWhitespace				)
	ON_COMMAND		( ID_OPTIONS_ALPHANUMERICCHARACTER	, OnCommandAlphaNumericCharacter	)
	ON_COMMAND		( ID_OPTIONS_ALPHABETICCHARACTER	, OnCommandAlphaCharacter			)
	ON_COMMAND		( ID_OPTIONS_DECIMALDIGIT			, OnCommandDecDigit					)
	ON_COMMAND		( ID_OPTIONS_HEXADECIMALNUMBER		, OnCommandHexNumber				)
	ON_COMMAND		( ID_OPTIONS_NUMBER					, OnCommandNumber					)
	ON_COMMAND		( ID_OPTIONS_INTEGER				, OnCommandInteger					)
	ON_COMMAND		( ID_OPTIONS_CCIDENTIFIER			, OnCommandCIdentifier				)
	ON_COMMAND		( ID_OPTIONS_ALPHABETICSTRING		, OnCommandAlphabeticString			)
	ON_COMMAND		( ID_OPTIONS2_FINDWHATTEXT			, OnCommandFindWhatText				)
	ON_COMMAND		( ID_OPTIONS2_TAGGEDEXPRESSION1		, OnCommandTaggedExpression1		)
	ON_COMMAND		( ID_OPTIONS2_TAGGEDEXPRESSION2		, OnCommandTaggedExpression2		)
	ON_COMMAND		( ID_OPTIONS2_TAGGEDEXPRESSION3		, OnCommandTaggedExpression3		)
	ON_COMMAND		( ID_OPTIONS2_TAGGEDEXPRESSION4		, OnCommandTaggedExpression4		)
	ON_COMMAND		( ID_OPTIONS2_TAGGEDEXPRESSION5		, OnCommandTaggedExpression5		)
	ON_COMMAND		( ID_OPTIONS2_TAGGEDEXPRESSION6		, OnCommandTaggedExpression6		)
	ON_COMMAND		( ID_OPTIONS2_TAGGEDEXPRESSION7		, OnCommandTaggedExpression7		)
	ON_COMMAND		( ID_OPTIONS2_TAGGEDEXPRESSION8		, OnCommandTaggedExpression8		)
	ON_COMMAND		( ID_OPTIONS2_TAGGEDEXPRESSION9		, OnCommandTaggedExpression9		)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//***************************************************************************************************
//**																					 OnInitDialog
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		Called to initialize the dialog
//**	@END
//***************************************************************************************************
//inline
BOOL CDialogSmartReplace::OnInitDialog() 
{
	//
	//	CALL BASE CLASS' IMPLEMENTATION
	//
	CDialog::OnInitDialog();

	//
	//	SETUP CONTROLS
	//
	this->m_ctrlBtnAdvanced	.SetWindowText( _T( "<< Si&mple" ) );

#ifdef NDEBUG
	this->GetDlgItem( IDC_DEBUG )->EnableWindow	( FALSE		);
	this->GetDlgItem( IDC_DEBUG )->ShowWindow	( SW_HIDE	);
#endif

	//
	//	LOAD PROFILE
	//
	this->LoadProfile();

	//
	//	UPDATE FIND STRING
	//
	this->UpdateFindStringEx();

	//
	//	SET THE FOCUS TO THE "Find What" COMBO BOX
	//
	this->GetDlgItem( IDC_COMBO_FIND_WHAT )->SetFocus();

	//
	//	RESET ABORT FLAG
	//
	this->m_bAborted = FALSE;

	//
	//	DO NOT MODIFY FOCUS
	//
	return FALSE;  
}

//***************************************************************************************************
//**																						  OnClose
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		Called when the window is about to close
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnClose() 
{
	//
	//	UPDATE MEMBERS FROM CONTROLS
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	WRITE PROFILE
	//
	this->WriteProfile();

	//
	//	CALL BASE CLASS' IMPLEMENTATION
	//
	CDialog::OnClose();
}

//***************************************************************************************************
//**																					   OnContinue
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnContinue() 
{
	//
	//	RESET ABORT FLAG
	//
	this->m_bAborted = FALSE;

	//
	//	UPDATE MEMBERS FROM CONTROLS	
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	UPDATE HISTORIES
	//
	this->UpdateHistories();

	//
	//	CHECK AVAILABILITY
	//
	if ( FALSE == this->GetTextSelection().IsValid() )
	{
		return;
	}

	//
	//	FIND TEXT
	//
	if ( FALSE == this->FindText() )
	{
		this->OnSearchComplete();
	}

	//
	//	CHECK FOR FINISH
	//
	if ( TRUE == this->m_bFileFinished )
	{
		this->OnSearchComplete();
	}
}

//***************************************************************************************************
//**																						OnReplace
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnReplace() 
{
	//
	//	RESET ABORT FLAG
	//
	this->m_bAborted = FALSE;

	//
	//	SET ASK PERMISISON FLAG
	//
	this->m_bAskPermission = this->m_bAskForExtendedOnly;

	//
	//	UPDATE MEMBERS FROM CONTROLS	
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	UPDATE HISTORIES
	//
	this->UpdateHistories();

	//
	//	CHECK FOR MATCH
	//
	if ( FALSE == this->GetTextSelection().IsValid() )
	{
		return;
	}

	//
	//	REPLACE NEXT
	//
	if ( FALSE == this->ReplaceNext() )
	{
		this->OnSearchComplete();
	}
}

//***************************************************************************************************
//**																					 OnReplaceAll
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnReplaceAll() 
{
	//
	//	RESET ABORT FLAG
	//
	this->m_bAborted = FALSE;

	//
	//	UPDATE MEMBERS FROM CONTROLS	
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	UPDATE HISTORIES
	//
	this->UpdateHistories();

	//
	//	REPLACE ALL
	//
	int iReplaced = 0;

	switch ( this->m_iReplaceWhere )
	{
										//
										//	CURRENT SELECTION
										//
		case EReplaceWhere_Selection:	this->m_bAskPermission = (FALSE == this->m_bAskForExtendedOnly) ? TRUE : FALSE;

										iReplaced = this->ReplaceAllSelection();	
										
										break;

										//
										//	CURRENT FILE
										//
		case EReplaceWhere_File		:	this->m_bAskPermission = (FALSE == this->m_bAskForExtendedOnly) ? TRUE : FALSE;

										iReplaced = this->ReplaceAll();	

										break;
					
										//
										//	EXTENDED
										//
		case EReplaceWhere_Extended	:	this->m_bAskPermission = TRUE;

										switch ( this->m_iReplaceWhereEx )
										{
																					//
																					//	ALL OPEN FILES
																					//
											case EReplaceWhereEx_AllOpen		:	iReplaced = this->ReplaceAllOpen		();	break;
																															
																					//										
																					//	ALL FILES IN PROJECT				
																					//										
											case EReplaceWhereEx_AllInProject	:	iReplaced = this->ReplaceAllProject		();	break;
																				
																					//
																					//	ALL FILES IN WORKSPACE
																					//
											case EReplaceWhereEx_AllInWorkspace	:	iReplaced = this->ReplaceAllWorkspace	();	break;

																					//
																					//	ALL FILES IN DIRECTORY
																					//
											case EReplaceWhereEx_AllInDirectory	:	iReplaced = this->ReplaceAllDirectory	();	break;

																					//
																					//	ALL FILES IN FILTER SETTINGS
																					//
											case EReplaceWhereEx_AllInFilters	:	iReplaced = this->ReplaceAllFilters		();	break;
										}
										break;
	}

	//
	//	DELGATE
	//
	this->OnSearchComplete( iReplaced <= 0 );
}

//***************************************************************************************************
//**																						 OnCancel
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCancel() 
{
	//
	//	CALL BASE CLASS' IMPLEMENTATION
	//
	CDialog::OnCancel();
}

//***************************************************************************************************
//**																					   OnAdvanced
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnAdvanced() 
{
	//
	//	UPDATE MEMBERS FROM CONTROLS	
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	CHECK STATE
	//
	CString strCaption	;	this->m_ctrlBtnAdvanced.GetWindowText( strCaption );
	BOOL	bOpen		= ( "Ad&vanced>>" == strCaption );

	//
	//	TOGGLE STATE
	//
	this->m_ctrlBtnAdvanced.SetWindowText( bOpen ? _T( "<< Si&mple" ) : _T( "Ad&vanced>>" ) );

	//
	//	RESIZE WINDOW
	//
	CRect rectPos;

	this->GetWindowRect	( rectPos );	rectPos.bottom += (bOpen ? 120 : -120);
	this->MoveWindow	( rectPos.left, rectPos.top, rectPos.Width(), rectPos.Height() );
}

//***************************************************************************************************
//**																						OnOptions
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnOptions() 
{
	//
	//	SETUP DIALOG
	//
	CDialogOptions dlgOptions( this );

	//
	//	EXCHANGE DATA TO DIALOG
	//
	dlgOptions.m_bAskForExtendedOnly = this->m_bAskForExtendedOnly	;
	dlgOptions.m_iConfirmReplacement = this->m_enuConfirmReplacement;
	dlgOptions.m_iSaveAndClose		 = this->m_enuSaveAndClose		;

	//
	//	SHOW DIALOG
	//
	if ( IDOK != dlgOptions.DoModal() )
	{
		return;
	}

	//
	//	EXCHANGE DATA FROM DIALOG
	//
	this->m_bAskForExtendedOnly		=										dlgOptions.m_bAskForExtendedOnly	 ;
	this->m_enuConfirmReplacement	= static_cast< EConfirmReplacement	> (	dlgOptions.m_iConfirmReplacement	);
	this->m_enuSaveAndClose			= static_cast< ESaveAndClose		> (	dlgOptions.m_iSaveAndClose			);

	//
	//	WRITE MODIFICATIONS TO PROFILE
	//
	CWinApp* pApp = ::AfxGetApp();

	CString strSection; 
			strSection.LoadString( IDS_PROFILE_SECTION );

	pApp->WriteProfileInt	( strSection, _T( "AskForExtendedOnly"	), this->m_bAskForExtendedOnly 		);
	pApp->WriteProfileInt	( strSection, _T( "ConfirmReplace"		), this->m_enuConfirmReplacement	);
	pApp->WriteProfileInt	( strSection, _T( "SaveAndClose"		), this->m_enuSaveAndClose			);
}

//***************************************************************************************************
//**																						OnFilters
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnFilters() 
{
	//
	//	SETUP DIALOG
	//
	CDialogFilters dlgFilters;

	//
	//	SET FILTERS
	//
	dlgFilters.SetFolders	( this->m_arrFolders	);
	dlgFilters.SetFileMasks	( this->m_arrFileMasks	);

	//
	//	DISPLAY DIALOG
	//
	if ( IDOK != dlgFilters.DoModal() )
	{
		return;
	}

	//
	//	STORE FILTERS
	//
	this->m_arrFolders	.RemoveAll();
	this->m_arrFileMasks.RemoveAll();

	dlgFilters.GetFolders	( this->m_arrFolders	);
	dlgFilters.GetFileMasks	( this->m_arrFileMasks	);

	//
	//	WRITE FILTERS
	//
	this->WriteFilters();
}

//***************************************************************************************************
//**																				OnBrowseDirectory
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnBrowseDirectory() 
{
	//
	//	UPDATE MEMBERS FROM CONTROLS
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	BROWSE FOLDER
	//
	CFolderDialog dlgFolder	( _T( "Select Search Directory" )
							, _T( "Select the place where you want to start your search from the list below:" )
							, this->m_strDirectory 
							);

	if ( IDOK != dlgFolder.DoModal() )
	{
		return;
	}

	//
	//	KEEP FOLDER
	//
	this->m_strDirectory = dlgFolder.GetPath();

	//
	//	UPDATE MEMBERS TO CONTROLS
	//
	this->UpdateData( EUpdateData_ToControls );

	//
	//	UPDATE HISTORY
	//
	this->UpdateHistoryDirectory();
}

//***************************************************************************************************
//**																		  OnContextMenuRegExpFind
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		Displays the regular expression context menu
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnContextMenuRegExpFind() 
{
	//
	//	LOAD CONTEXT MENU
	//
	CMenu	menuContext;
			menuContext.LoadMenu( IDM_REGEXP );

	//
	//	GET SUB MENU
	//
	CMenu*  pMenu = menuContext.GetSubMenu( EMenuRegExp_Find ); 

	//
	//	GET CURSOR POSITION	
	//
	POINT ptCursor;	::GetCursorPos( &ptCursor );

	//
	//	TRACK POPUP MENU
	//
	pMenu->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, ptCursor.x, ptCursor.y, this, NULL );	
}

//***************************************************************************************************
//**																	   OnContextMenuRegExpReplace
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		Displays the regular expression context menu
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnContextMenuRegExpReplace() 
{
	//
	//	LOAD CONTEXT MENU
	//
	CMenu	menuContext;
			menuContext.LoadMenu( IDM_REGEXP );

	//
	//	GET SUB MENU
	//
	CMenu*  pMenu = menuContext.GetSubMenu( EMenuRegExp_Replace ); 

	//
	//	GET CURSOR POSITION	
	//
	POINT ptCursor;	::GetCursorPos( &ptCursor );

	//
	//	TRACK POPUP MENU
	//
	pMenu->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, ptCursor.x, ptCursor.y, this, NULL );	
}

//***************************************************************************************************
//**																						  OnDebug
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnDebug() 
{
	#define TRI( Func, Interface  )	{ TRACE3( "[SmartReplace] %-25s: %-40s->m_lRefCount == %d\n", #Func, #Interface, ::g_GetRefCount(  Interface ) ); }
	#define TRC( Func, Interface )	{ TRACE3( "[SmartReplace] %-25s: %-40s->m_lRefCount == %d\n", #Func, #Interface, ::g_GetRefCount( *Interface ) ); }

	//
	//	CHECK REFERENCE COUNTING FOR SAMPLE CASE
	//
	TRC( Init, m_pIApplication );
	{
		CIDocuments pIDocuments = this->m_pIApplication.GetDocuments();	TRC( GetDocuments, m_pIApplication );	TRC( GetDocuments, pIDocuments );
	}

	TRC( Exit, m_pIApplication );

	#undef TRI
	#undef TRC
}

//***************************************************************************************************
//**																				 OnCheckMatchCase
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCheckMatchCase() 
{
	//
	//	UPDATE MEMBERS FROM CONTROLS
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	UPDATE CONTROLS
	//
	this->UpdateControls();
}

//***************************************************************************************************
//**																		 OnCheckRegularExpression
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCheckRegularExpression() 
{
	//
	//	UPDATE MEMBERS FROM CONTROLS
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	UPDATE CONTROLS
	//
	this->UpdateControls();
}

//***************************************************************************************************
//**																				 OnRadioSelection
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnRadioSelection() 
{
	//
	//	UPDATE MEMBERS FROM CONTROLS
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	UPDATE CONTROLS
	//
	this->UpdateControls();
}

//***************************************************************************************************
//**																					  OnRadioFile
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnRadioFile() 
{
	//
	//	UPDATE MEMBERS FROM CONTROLS
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	UPDATE CONTROLS
	//
	this->UpdateControls();
}

//***************************************************************************************************
//**																				  OnRadioExtended
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnRadioExtended() 
{
	//
	//	UPDATE MEMBERS FROM CONTROLS
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	UPDATE CONTROLS
	//
	this->UpdateControls();
}

//***************************************************************************************************
//**																	  OnSelEndOkComboReplaceWhere
//***************************************************************************************************
//**	@DOC		MESSAGES
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnSelEndOkComboReplaceWhere() 
{
	//
	//	UPDATE MEMBERS FROM CONTROLS
	//
	this->UpdateData( EUpdateData_FromControls );

	//
	//	UPDATE CONTROLS
	//
	this->UpdateControls();
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandAnyChar()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_AnyChar ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandInRange()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_InRange ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandNotInRange()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_NotInRange ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandBeginOfLine()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_BeginOfLine ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandEndOfLine()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_EndOfLine ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandTaggedExp()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_TaggedExpression ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandNot()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_Not ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandOr()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_Or ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommand0OrMore()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_ZeroOrMore ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommand1OrMore()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_OneOrMore ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandGroup()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_Group ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandWhitespace()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_Whitespace ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandAlphaNumericCharacter()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_AlphaNumericCharacter ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandAlphaCharacter()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_AlphaCharacter ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandDecDigit()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_DecimalDigit ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandHexNumber()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_HexNumber ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandNumber()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_DecimalNumber ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandInteger()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_Integer ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandCIdentifier()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_Identifier ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandAlphabeticString()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_AlphabeticString ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandQuotedString()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpFind[ ERegExpFind_QuotedString ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandFindWhatText()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpReplace[ ERegExpReplace_FindWhatText ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandTaggedExpression1()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpReplace[ ERegExpReplace_TaggedExpression1 ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandTaggedExpression2()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpReplace[ ERegExpReplace_TaggedExpression2 ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandTaggedExpression3()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpReplace[ ERegExpReplace_TaggedExpression3 ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandTaggedExpression4()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpReplace[ ERegExpReplace_TaggedExpression4 ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandTaggedExpression5()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpReplace[ ERegExpReplace_TaggedExpression5 ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandTaggedExpression6()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpReplace[ ERegExpReplace_TaggedExpression6 ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandTaggedExpression7()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpReplace[ ERegExpReplace_TaggedExpression7 ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandTaggedExpression8()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpReplace[ ERegExpReplace_TaggedExpression8 ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}

//***************************************************************************************************
//**																	  
//***************************************************************************************************
//**	@DOC		MESSAGES COMMANDS
//**	@MFUNC		
//**	@END
//***************************************************************************************************
//inline
void CDialogSmartReplace::OnCommandTaggedExpression9()
{
	//
	//	GET TEXT
	//
	const char* pszText = this->ms_ppszRegExpReplace[ ERegExpReplace_TaggedExpression9 ][ this->m_lRegExpEmulation ];

	//
	//	ADD TEXT
	//
	this->AddText( this->m_ctrlComboFindWhat, pszText );
}
